{% extends "layout.html" %}
{% block content %}

<style>
    .info-callout {
        border-left: 5px solid #17a2b8; /* Bootstrap info color */
        background-color: #e9f7fb; /* Lightened info background */
        padding: 15px;
        margin-bottom: 5px;
        margin-top: 20px;
        border-radius: 4px;
        color: #0c5460; /* Bootstrap info text color */
    }

    .warning-callout {
        border-left: 5px solid #ffc107; /* Bootstrap warning color */
        background-color: #fff3cd; /* Lightened warning background */
        padding: 15px;
        margin-bottom: 5px;
        margin-top: 20px;
        border-radius: 4px;
        color: #856404; /* Bootstrap warning text color */
    }
    
    /* .callout-title {
        font-size: 18px;
        font-weight: 600;
        margin-bottom: 10px;
    } */
</style>

<div class="content-section">
    <h1 class="display-4 text-center mb-3">Report Redaction</h1>


    <form action="" method="post" enctype="multipart/form-data" class="container mt-4">

        {{ form.hidden_tag() }}
    
        <!-- Combined Fieldset -->
        <fieldset class="border rounded p-4 mb-4">
            <legend class="w-auto px-2 bg-white text-dark fw-bold fs-4 border-bottom pb-2 mb-3">File Uploads</legend>
    
            <!-- LLM Output File -->
            <div class="mb-4">
                <h5 class="d-flex align-items-center">
                    <i class="bi bi-file-earmark-zip fs-3 me-2"></i>
                    LLM Output File (.zip)
                </h5>
                <div class="input-group">
                    {% if form.file.errors %}
                        {{ form.file(class="form-control is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.file.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.file(class="form-control") }}
                    {% endif %}
                </div>
            </div>
    
            <!-- Annotation File -->
            <div class="mb-4">
                <h5 class="d-flex align-items-center">
                    <i class="bi bi-file-earmark-spreadsheet fs-3 me-2"></i>
                    Optional: Annotation File (.zip)
                </h5>
                <div class="input-group">
                    {% if form.annotation_file.errors %}
                        {{ form.annotation_file(class="form-control is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.annotation_file.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.annotation_file(class="form-control") }}
                    {% endif %}
                </div>
            </div>
        </fieldset>
    
        <!-- Redaction Settings -->
        <fieldset class="border rounded p-4 mb-4">
            <legend class="w-auto px-2 bg-white text-dark fw-bold fs-4 border-bottom pb-2 mb-3">Redaction Settings</legend>
    
            <!-- Fuzzy Matching Toggle -->
        <div class="form-check form-switch mb-4">
            {% if form.enable_fuzzy.errors %}
                {{ form.enable_fuzzy(class="form-check-input is-invalid", id="enable_fuzzy") }}
                <div class="invalid-feedback">
                    {% for error in form.enable_fuzzy.errors %}
                        <span>{{ error }}</span>
                    {% endfor %}
                </div>
            {% else %}
                {{ form.enable_fuzzy(class="form-check-input", id="enable_fuzzy") }}
            {% endif %}
            <label class="form-check-label d-flex align-items-center" for="enable_fuzzy">
                Enable Fuzzy Matching
            </label>
        </div>

        <!-- Fuzzy Settings Fields -->
        <div id="fuzzy-settings" class="fuzzy-settings">
            <!-- Threshold and Scorer -->
            <div class="row mb-4">
                <div class="col-md-6 mb-3">
                    <div class="input-group">
                        <span class="input-group-text"><i class="bi bi-speedometer"></i></span>
                        {% if form.threshold.errors %}
                            {{ form.threshold(class="form-control is-invalid") }}
                            <div class="invalid-feedback">
                                {% for error in form.threshold.errors %}
                                    <span>{{ error }}</span>
                                {% endfor %}
                            </div>
                        {% else %}
                            {{ form.threshold(class="form-control") }}
                        {% endif %}
                    </div>
                    <label for="threshold" class="form-label">Threshold</label>
                </div>
                <div class="col-md-6 mb-3">
                    <div class="input-group">
                        <span class="input-group-text"><i class="bi bi-award fs-5"></i></span>
                        {% if form.scorer.errors %}
                            {{ form.scorer(class="form-control is-invalid") }}
                            <div class="invalid-feedback">
                                {% for error in form.scorer.errors %}
                                    <span>{{ error }}</span>
                                {% endfor %}
                            </div>
                        {% else %}
                            {{ form.scorer(class="form-select") }}
                        {% endif %}
                    </div>
                    <label for="scorer" class="form-label">Scorer</label>
                </div>
            </div>
        </div>
    
            <!-- Exclude Single Characters -->
            <div class="form-check mb-4">
                {% if form.exclude_single_chars.errors %}
                    {{ form.exclude_single_chars(class="form-check-input is-invalid") }}
                    <div class="invalid-feedback">
                        {% for error in form.exclude_single_chars.errors %}
                            <span>{{ error }}</span>
                        {% endfor %}
                    </div>
                {% else %}
                    {{ form.exclude_single_chars(class="form-check-input") }}
                {% endif %}
                <label class="form-check-label" for="exclude_single_chars">
                    Exclude Single Characters
                </label>
            </div>
    
            <!-- Ignore Labels as Text Field -->
            <div class="mb-4">
                <div class="input-group">
                    <span class="input-group-text"><i class="bi bi-tag fs-5"></i></span>
                    {% if form.ignore_labels.errors %}
                        {{ form.ignore_labels(class="form-control is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.ignore_labels.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.ignore_labels(class="form-control") }}
                    {% endif %}
                </div>
                <label for="ignore_labels" class="form-label">Ignore Labels (comma-separated)</label>
            </div>
        </fieldset>
    
        <!-- Submit Buttons -->
        <div class="row mb-4">
            <div class="col-md-6 mb-3">
                <button type="submit" name="submit-metrics" class="btn btn-primary w-100">
                    <i class="bi bi-bar-chart-line me-2"></i> Report Redaction Metrics
                </button>
            </div>
            <!--
            <div class="col-md-4 mb-3">
                <button type="submit" name="submit-viewer" class="btn btn-primary w-100">
                    <i class="bi bi-eye me-2"></i> Report Redaction Viewer (document-wise)
                </button>
            </div>-->
            <div class="col-md-6 mb-3">
                <button type="submit" name="submit-redaction-download" class="btn btn-primary w-100">
                    <i class="bi bi-download me-2"></i> Download Redacted Reports
                </button>
            </div>
        </div>

            
    
            <div class="info-callout">
                <h4 class="callout-title">Information</h4>
                <p>The ground truth <b>Annotation</b> must be created using the <a href="https://inception-project.github.io/">Inception Annotation Tool</a>.
                <ol>
                    <li>Download Inception</li>
                    <li>Start a basic annotation project, upload the pdf files and annotate the parts of the reports you want to anonymize. Refer to the <a href="https://inception-project.github.io/releases/32.2/docs/user-guide.html">Inception User Guide</a>
                    </li>
                    <li>Export the annotated reports in the UIMA CAS JSON format (UIMA CAS JSON 0.4.0)
                    </li>
                    <li>Make sure the filename of the exported json files matches the filename of the pdf files (except the extension like .json and .pdf)
                    </li>
                    <li>Create a zip file of the exported json files (zip the json files directly, not a directory where they are located!)
                    </li>
                </ol>

                The detected information to redact from the LLM will be matched with the document-text in an case-insensitive way. German umlauts are taken care of and both versions are matched.
                <br>
                <br>
                You can use fuzzy matching (still match even if the exact match is not found) by selecting the <b>Fuzzy Matching</b> option. You can set a similarity threshold (min. similarity that this is indeed the information to match), the method and an option to exclude single characters (like a house number which would lead to all occurrences of this number in the document being matched).

                <br>
                <br>

                The <b>metrics</b> are calculated on a per-character basis for the whole text ignoring whitespaces and other special characters.
                <br>
                <br>
                You can also directly download the redacted documents: <b>Download Redacted Documents</b>
                </p>
            </div>

        </fieldset>

        

    </form>
</div>
<hr class="bg-danger border-2 border-top border-dark" />

<div class="content-section pt-3">

    <div class="container mt-5">
        <h1 class="display-4 text-center mb-4">Report Redaction Progress</h1>
        {% for job_id, progress_tuple in progress.items() %}
        <div class="card mb-4 shadow-sm">
            <div class="card-body">
                <div class="d-flex justify-content-between align-items-center mb-2">
                    <h3 class="h5 mb-0">Job {{ job_id }}</h3>
                    {% if progress_tuple[0] == progress_tuple[1] %}
                    <a id="download-{{ job_id }}" href="/reportredactionmetrics/{{ job_id }}" class="btn btn-outline-success">
                        <i class="bi bi-bar-chart-line"></i> View Metrics
                    </a>
                    {% elif progress_tuple[2] %}
                    <a id="download-{{ job_id }}" href="#" class="btn btn-outline-success disabled" disabled>
                        <i class="bi bi-bar-chart-line"></i> Processing ...
                    </a>
                    {% else %}
                    <a id="download-{{ job_id }}" href="#" class="btn btn-outline-danger disabled" disabled>
                        <i class="bi bi-x-circle"></i> Failed
                    </a>
                    {% endif %}
                </div>
                <div class="progress" style="height: 25px;">
                    {% if progress_tuple[2] %}
                    <div id="progress-{{ job_id }}" class="progress-bar bg-success" role="progressbar" style="width: {{ (progress_tuple[0] / progress_tuple[1]) * 100 }}%;" aria-valuenow="{{ progress_tuple[0] }}" aria-valuemin="0" aria-valuemax="{{ progress_tuple[1] }}">
                        {{ progress_tuple[0] }} / {{ progress_tuple[1] }}
                    </div>
                    {% else %}
                    <div id="progress-{{ job_id }}" class="progress-bar bg-danger" role="progressbar" style="width: 100%;" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
                        {{ progress_tuple[0] }} / {{ progress_tuple[1] }} FAILED
                    </div>
                    {% endif %}
                </div>
            </div>
        </div>
        {% endfor %}
    </div>
    
    <div id="flash-messages" class="container"></div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.3/socket.io.js"></script>
<script>
    document.addEventListener('DOMContentLoaded', function () {
        var fuzzySwitch = document.getElementById('enable_fuzzy');
        var fuzzySettings = document.getElementById('fuzzy-settings');

        function toggleFuzzySettings() {
            if (fuzzySwitch.checked) {
                fuzzySettings.style.display = 'block';
            } else {
                fuzzySettings.style.display = 'none';
            }
        }

        // Initial check on page load
        toggleFuzzySettings();

        // Toggle settings when switch changes
        fuzzySwitch.addEventListener('change', toggleFuzzySettings);
    });


    var socket = io.connect('http://' + document.domain + ':' + location.port);

    socket.on('progress_update', function (data) {
        var job_id = data.job_id;
        var progress = data.progress;
        var totalSteps = data.total;

        // Update progress bar for the corresponding job
        var progressBar = document.getElementById('progress-' + job_id);
        if (progressBar) {
            progressBar.style.width = (progress / totalSteps) * 100 + '%';
            progressBar.innerText = progress + ' / ' + totalSteps;
        }
    });

    // On progress_warning (with job_id and message), make progress bar yellow and flash the message in yellow with bootstrap 
    socket.on('progress_warning', function (data) {
        var job_id = data.job_id;
        var warning_message = data.message;
        var progressBar = document.getElementById('progress-' + job_id);
        progressBar.className = 'progress-bar bg-warning';

        var flashMessageContainer = document.getElementById('flash-messages');
        var flashMessage = document.createElement('div');
        flashMessage.className = 'alert alert-warning alert-dismissible fade show';
        flashMessage.role = 'alert';
        flashMessage.innerHTML = '<strong>Warning!</strong> ' + warning_message +
            '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>';
        flashMessageContainer.appendChild(flashMessage);

        // Close flashed message when close button is clicked
        flashMessage.querySelector('.btn-close').addEventListener('click', function () {
            flashMessageContainer.removeChild(flashMessage);
        });


    });

    socket.on('progress_complete', function (data) {
        var job_id = data.job_id;
        var progressBar = document.getElementById('progress-' + job_id);

        // Enable download button
        var downloadLink = document.getElementById('download-' + job_id);
        downloadLink.href = '/reportredactionmetrics/' + job_id;
        downloadLink.classList.remove('disabled');
        downloadLink.innerHTML = '<i class="bi bi-bar-chart-line">View Metrics</i>';
        downloadLink.removeAttribute('disabled');

        var progressbar = document.getElementById('progress-' + job_id);
        progressbar.className = 'progress-bar bg-success';
        progressbar.innerText = 'Completed';
        progressbar.style.width = '100%';
    });

    socket.on('progress_failed', function (data) {

        var job_id = data.job_id;
        var progressBar = document.getElementById('progress-' + job_id);

        // Make progress bar red and state failure
        progressBar.className = 'progress-bar bg-danger';
        progressBar.innerText = 'Failed';
        progressBar.style.width = '100%';

        var downloadLink = document.getElementById('download-' + job_id);
        downloadLink.classList.add('disabled');
        downloadLink.setAttribute('disabled', 'disabled');
        downloadLink.className = 'btn btn-danger disabled';

    });



</script>

{% endblock %}